最近一篇博客已经是几个月以前写的了,再次不忍直视 -_-|||

决定要把mongo的高级应用第二篇继续推后,先写一下这篇博文。

Echarts-PHP项目上线已经有些日子了,在未做任何推广的情况下,安装量在低速提升,截至到现在,下载量已经到17k+。也算有一个小的用户群体,那么一些优化建议也被反馈到这里。其中有一个是一直想做,但没有做的。

根源

在这个项目设计之初,就想要用property来做前端的json数据绑定。原因是,echarts各种属性更新很频繁,而用property可以完美解决这个问题,用户想怎么赋值属性就怎么赋值,非常灵活,并且代码看起来超级简单有木有?其实归根到底还是一个字:懒。

问题来了

那么问题来了,没有方法提供给用户使用,并且property下面还有各种子property。于是乎在PHPStorm下各种property带着下划的波浪线,提示Field Accessed via magic method 。那么怎么才能在PHPStorm这种高大上的IDE中自动提示这些可用的property呢?

怎么办

打开http://echarts.baidu.com/option.html,看了一下,option的数量实在太多,直接打消了手动加PHPDoc的想法,只怪太懒。。。那么有没有办法自动生成PHPDoc呢?好想法。接下来看这个网页的源代码,看看能否通过写脚本把需要的信息抓下来。嗯,发现所有option都是异步获取的。那么按下F12,看一下这些数据哪里来的。马上找到了这个:http://echarts.baidu.com/documents/cn/option.json 这不正是想要的吗?

开始动工

接下来的问题是怎么写这些PHPDoc,能否有办法不产生实际代码的情况下来生成这些PHPDoc呢?查看PHPDoc的官方网站和谷歌,查找PHPDoc能否在注释中定义类,能否设置类的子属性。很遗憾没有找到,那只有最后一条路了,生成一堆带有property的类,然后给每个property加上PHPDoc,这样IDE就能自动提示了!

需要注意的是,这种方式虽然生成了很多文件、目录,但对你的项目的代码是没依赖的,也就是实际代码执行时不会自动加载这些类,他们仅给IDE自动提示用。

源码: https://github.com/hisune/Echarts-PHP/blob/master/src/Doc/AutoGenerate.php

核心方法,是个递归:

protected function _properties($properties, $dir = '')
{
    if(!$dir){
        echo "/**\r\n * Class ECharts\r\n * Created by Hisune EchartsPHP AutoGenerate.\r\n * @package Hisune\\EchartsPHP\r\n * \r\n";
    }

    foreach($properties as $top => $property){
        $classPropertyString = '';
        $top = ucfirst($top);

        if(isset($property['properties'])){
            foreach ($property['properties'] as $classPropertyName => $classProperty){
                $classPropertyString .= $this->_propertyTemplate($classPropertyName, $classProperty, $top);
            }
            $this->_properties($property['properties'], $dir . '/' . $top);
        }

        $dirToWrite = $this->dir . $dir;
        if($classPropertyString){
            if(!file_exists($dirToWrite)){
                mkdir($dirToWrite, 0777, true);
            }
            file_put_contents($dirToWrite . '/' . $top . '.php', $this->_classTemplate($top, $dir, $classPropertyString));
        }

        // 输出ECharts类的property doc
        if(!$dir){
            $description = isset($property['descriptionCN']) ? $this->_replaceDescription($property['descriptionCN'], false) . "\r\n *" : '';
            if(file_exists($dirToWrite . '/' . $top . '.php')){
                echo " * @property Doc\\IDE\\{$top} \$" . lcfirst($top) . "\r\n *   " . $description . "\r\n";
            }else{
                echo " * @property callable \$" . strtolower($top) . "\r\n *   " . $description . "\r\n";
            }
        }
    }

    if(!$dir){
        echo " */\r\n";
    }
}

执行后,嗯,很完美!但打开几个文件与官方文档进行比对,傻眼了,为何有些属性官方文档有,这里没有呢?

接下来查找option.json的相关字段,明明option.json中也没有,那么官方文档为何会有?难道有js进行特殊处理?在尝试着生成中文版的PHPDoc的时候,才发现被这个option.json坑了,原来en版的option.json是不完整的。。。-_-|||,那么就用中文版吧!

如何生成自己的PHPDoc

那么,如果echarts的文档更新了,但ECharts-PHP还没更新怎么办?有一种不推荐的做法可以临时解决。

cd Echarts-PHP/src/Doc
php AutoGenerate.php

执行就可以了,这个cli文件可以传递一个参数,参数值默认en,还有一个值是cn。没错就是生成PHPDoc的默认语言,如果要保持最新,请加参数cn。执行后会自动从echarts线上拉取option.json进行PHPDoc的更新,同时,输出Hisune\EchartsPHP\ECharts类的注释,复制这些注释,替换掉Hisune\EchartsPHP\ECharts类的注释即可。

当然,并不推荐使用这种方法来更新PHPDoc,最好联系本人,或提交PR。^_^

如果您觉得您在我这里学到了新姿势,博主支持转载,姿势本身就是用来相互学习的。同时,本站文章如未注明均为 hisune 原创 请尊重劳动成果 转载请注明 转自: 利用echarts的option.json自动生成ECharts-PHP的property PHPDoc - hisune.com